{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# NumPy: 固定类型的Python数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">### 相关参考资料\n",
    "bilibili视频可参考：  \n",
    "(1)[【python教程】数据分析——numpy、pandas、matplotlib](https://www.bilibili.com/video/BV1hx411d7jb?from=search&seid=12190247343680651243)  \n",
    "(2)[莫烦 Python 数据处理教程](https://www.bilibili.com/video/BV1Ex411L7oT?from=search&seid=12190247343680651243)  \n",
    "相关书籍可参考:  \n",
    "《Python数据科学手册》"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**NumPy**，便是**Numerical Python**的简称。意为：数字的Python  \n",
    "在某些方面，**NumPy数组**与Python内置的**列表类型**非常相似。但随着数组在维度上变大，Numpy数组提供了更高效的存储和数据操作。**NumPy数组**是**Python数据科学工具生态系统**的**核心**。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. NumPy数组基础"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 NumPy数组的属性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***1***）**随机种子值: np.random.seed( )**：使用NumPy的随机数生成器时进行设置，以确保**每次都可以生成同样的随机数组**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(0) #设置随机数种子\n",
    "x1 = np.random.randint(10, size = 6) #一维数组\n",
    "x2 = np.random.randint(10, size = (3, 4)) #二维数组\n",
    "x3 = np.random.randint(10, size = (3, 4, 5)) #二维数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***2***）数组的**维度：.ndim**；**每个维度**的大小**：.shape**；数组的**总大小：.size**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x3 ndim:  3\n",
      "x3 shape:  (3, 4, 5)\n",
      "x3 size:  60\n"
     ]
    }
   ],
   "source": [
    "print('x3 ndim: ', x3.ndim)\n",
    "print('x3 shape: ', x3.shape)\n",
    "print('x3 size: ', x3.size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***3***）数组的**数据类型: .dtype**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x3 type:  int32\n"
     ]
    }
   ],
   "source": [
    "print('x3 type: ', x3.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***4***）**每个元素**字节大小： **.itemsize**；**总字节**大小： **.nbytes**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x3 itemsize:  4\n",
      "x3 nbytes:  240\n"
     ]
    }
   ],
   "source": [
    "print('x3 itemsize: ', x3.itemsize)\n",
    "print('x3 nbytes: ', x3.nbytes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 数组索引：获取单个元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***1***）**正向索引单个元素**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "print(x1[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***2***）**从末尾索引单个元素**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n"
     ]
    }
   ],
   "source": [
    "print(x1[-1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***3***）**多维数组索引用逗号隔开**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n",
      "7\n"
     ]
    }
   ],
   "source": [
    "print(x2[1, 0])\n",
    "print(x3[2, 1, 0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可直接修改元素的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 5 2 4]\n",
      " [1 6 8 8]\n",
      " [1 6 7 7]]\n"
     ]
    }
   ],
   "source": [
    "x2[1, 0] = 1\n",
    "print(x2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ***注意***  \n",
    " *1*.NumPy数组是**固定类型**的，所以将一个**浮点值**插入一个**整型数组**时，**浮点值会被截短成整型**，如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 5 2 4]\n",
      " [3 6 8 8]\n",
      " [1 6 7 7]]\n"
     ]
    }
   ],
   "source": [
    "x2[1, 0] = 3.14\n",
    "print(x2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 数组切片(slice)：获取子数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "切片符号通常用**冒号（:）**表示。**NumPy切片语法**和**Python列表的切片语法**相同。标准形式为：  \n",
    "    ***x[start:stop:stop]***  \n",
    "如果以上3个参数都未指定，那么它们会被设置为默认值：  \n",
    "start = 0  \n",
    "stop = 维度的大小（size of dimension）  \n",
    "step = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***1***）**对于一维子数组**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.arange(10)\n",
    "x[:5] #前五个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[5:] #5之后的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 2, 4, 6, 8])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[::2] #每隔一个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[::-1] #逆序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5, 3, 1])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[5::-2] #从索引5开始每隔一个元素逆序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***2***）**对于多维子数组**。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "多维情况下**每一维**与一维相同，不同维之间用逗号分隔。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3, 5, 2],\n",
       "       [3, 6, 8]])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x2[:2, :3] #前两行，前三列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3, 2],\n",
       "       [3, 8],\n",
       "       [1, 7]])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x2[:, ::2] #所有行，每隔一列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[7, 7, 6, 1],\n",
       "       [8, 8, 6, 3],\n",
       "       [4, 2, 5, 3]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x2[::-1, ::-1] #逆序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***3***）**获取数组的行和列**。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "常见的需求是获取数组的**单行**和**单列**，可以通过将**索引**和**切片**组合来实现此功能,用一个**冒号（:）**来表示**空切片**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 3 1]\n",
      "[3 5 2 4]\n"
     ]
    }
   ],
   "source": [
    "print(x2[:, 0]) #第一列\n",
    "print(x2[0, :]) #第一行"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在**获取行**时，处于简洁性考虑，可以省略空的切片。如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 5 2 4]\n"
     ]
    }
   ],
   "source": [
    "print(x2[0]) #等于x2[0, :]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ***注意***  \n",
    " *1*.对于**切片**而言，**NumPy数组**切片返回的是数组数据的**视图**，改变切片的值，则原数组的值也会相应改变，而**Python列表**返回的是**副本**，区别如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python列表改变后: [1, 2, 3, 4, 5]\n",
      "NumPy数组改变后: [ 1 99  3  4  5]\n"
     ]
    }
   ],
   "source": [
    "list1 = [1, 2, 3, 4, 5]\n",
    "array1 = np.array(list1)\n",
    "sub_list = list1[1:4]\n",
    "sub_array = array1[1:4]\n",
    "sub_list[0] = 99\n",
    "sub_array[0] = 99\n",
    "print('Python列表改变后:', list1)\n",
    "print('NumPy数组改变后:', array1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时不希望如此，则可**使用.copy()方法**进行复制，如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NumPy数组改变后: [1 2 3 4 5]\n"
     ]
    }
   ],
   "source": [
    "list1 = [1, 2, 3, 4, 5]\n",
    "array1 = np.array(list1)\n",
    "sub_array = array1[1:4].copy()\n",
    "sub_array[0] = 99\n",
    "print('NumPy数组改变后:', array1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ### 3.4 数组的变形"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组的变形通过**reshape()函数**来实现。  \n",
    "如将数字1~9放入3×3的矩阵中，可采用如下方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "grid = np.arange(1, 10).reshape((3, 3))\n",
    "print(grid)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ***注意***  \n",
    " *1*.对于reshape()函数，**原始数组的大小**必须和**变形后的数组大小（即size）**一致。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "另外，还有常见的用法，将**一维数组**变为**二维的行或列**。这可以通过**reshape()函数**来实现，也可通过**newaxis关键字**来实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]]\n",
      "[[1 2 3]]\n",
      "[[1]\n",
      " [2]\n",
      " [3]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1, 2, 3])\n",
    "print(x.reshape((1,3))) #通过变形变为行向量\n",
    "print(x[np.newaxis,:])  #通过newaxis变为行向量\n",
    "print(x[:, np.newaxis]) #通过newaxis变为列向量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ### 3.5 数组的拼接和分裂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 一. 数组的拼接"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***1***）**np.concatenate**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "拼接**两个**数组为一个："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "x_y = np.concatenate([x, y])\n",
    "print(x_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "拼接**多个**数组为一个："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "z = np.array([7, 8, 9])\n",
    "x_y_z = np.concatenate([x, y, z])\n",
    "print(x_y_z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于**二维数组**进行拼接："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [1 2 3]\n",
      " [4 5 6]\n",
      " [4 5 6]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1, 2, 3], [1, 2, 3]])\n",
    "y = np.array([[4, 5, 6], [4, 5, 6]])\n",
    "x_y = np.concatenate([x, y])\n",
    "print(x_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于**二维数组沿特定轴**进行拼接："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3 4 5 6]\n",
      " [1 2 3 4 5 6]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1, 2, 3], [1, 2, 3]])\n",
    "y = np.array([[4, 5, 6], [4, 5, 6]])\n",
    "x_y = np.concatenate([x, y], axis = 1) #axis从0开始索引\n",
    "print(x_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***2***）**np.vstack（垂直栈）**和**np.hstack（水平栈）**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当沿着固定维度处理数据时，使用**np.vstack(垂直栈)**和**np.hstack水平栈**会更简洁。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n"
     ]
    }
   ],
   "source": [
    "#vstack\n",
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "print(np.vstack([x, y]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6]\n"
     ]
    }
   ],
   "source": [
    "#hstack\n",
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "print(np.hstack([x, y]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此外，还有**np.dstack**沿着第三个维度拼接数组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[[1 4]\n",
      "  [2 5]\n",
      "  [3 6]]]\n"
     ]
    }
   ],
   "source": [
    "#dstack\n",
    "x = np.array([1, 2, 3])\n",
    "y = np.array([4, 5, 6])\n",
    "print(np.dstack([x, y]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 二.  数组的分裂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "具体思想为设置一个**索引列表**作为参数，记录**分裂点的位置**："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***1***）**np.split**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3] [4 5] [6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(1, 10)\n",
    "x1, x2, x3 = np.split(x, [3, 5]) #此时3，5即为分裂点的位置\n",
    "print(x1, x2, x3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***2***）**np.hsplit**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "up: [[ 0  1]\n",
      " [ 4  5]\n",
      " [ 8  9]\n",
      " [12 13]] \n",
      " low: [[ 2  3]\n",
      " [ 6  7]\n",
      " [10 11]\n",
      " [14 15]]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(16).reshape((4, 4))\n",
    "upper, lower = np.hsplit(x, [2])\n",
    "print('up:',upper, '\\n','low:',lower)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（***3***）**np.vsplit**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "left: [[0 1 2 3]\n",
      " [4 5 6 7]] \n",
      " right: [[ 8  9 10 11]\n",
      " [12 13 14 15]]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(16).reshape((4, 4))\n",
    "left, right = np.vsplit(x, [2])\n",
    "print('left:',left, '\\n','right:',right)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样，**np.dsplit**会将数组沿着第三个维度分裂（这在**三维数组**中会用到，低维数组中不会用到）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "261.812px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
